﻿/******************************************************************************
 * SunnyUI 开源控件库、工具类库、扩展类库、多页面开发框架。
 * CopyRight (C) 2012-2021 ShenYongHua(沈永华).
 * QQ群：56829229 QQ：17612584 EMail：SunnyUI@QQ.Com
 *
 * Blog:   https://www.cnblogs.com/yhuse
 * Gitee:  https://gitee.com/yhuse/SunnyUI
 * GitHub: https://github.com/yhuse/SunnyUI
 *
 * SunnyUI.dll can be used for free under the GPL-3.0 license.
 * If you use this code, please keep this note.
 * 如果您使用此代码，请保留此说明。
 ******************************************************************************
 * 文件名称: UIncreaseData.cs
 * 文件说明: 自增长数据基类
 * 当前版本: V3.0
 * 创建日期: 2021-03-13
 *
 * 2020-09-23: V3.0.2 增加文件说明
******************************************************************************/

using System;

namespace Sunny.UI
{
    public class IncreaseData<T>
    {
        public IncreaseData(int level = 0, int baseValue = 4)
        {
            LevelBaseValue = baseValue;
            Level = level;
            Clear();
        }

        private int level;

        private readonly int LevelBaseValue;

        public int Level
        {
            get => level;
            private set
            {
                level = value;
                Interval = (int)Math.Pow(LevelBaseValue, level);
            }
        }

        private int Interval;

        public void Clear()
        {
            Value = new T[16];
            Count = 0;
            Index = 0;
        }

        public T[] Value { get; private set; }

        public int Count { get; private set; }

        private int Index { get; set; }

        public bool Add(T value)
        {
            bool isAdd = false;
            if (Interval == 1 || Index.Mod(Interval) == 0)
            {
                if (Count == Value.Length)
                {
                    T[] temp = new T[Value.Length * 2];
                    Array.Copy(Value, temp, Value.Length);
                    Value = temp;
                }

                Value[Count] = value;
                Count++;
                isAdd = true;
            }

            Index++;
            return isAdd;
        }

        public T this[int index]
        {
            get => index.InRange(0, Count - 1) ? Value[index] : default;
            set
            {
                if (index.InRange(0, Count - 1))
                    Value[index] = value;
            }
        }

        public void Set(int dataLevel, T[] value)
        {
            Level = dataLevel;
            Count = value.Length;
            Index = 0;
            var s = Math.Log(Count, 2);
            int len = (int)(Math.Pow(2, (int)s + 1));
            Value = new T[len];
            Array.Copy(value, 0, Value, 0, Count);
        }
    }
}
